/*************************************************************************
	> File Name: myBuffer.c
	> Author: H.M. Lau
	> Mail: hm.lau@outlook.com
	> Created Time: 2023/09/01 20:40
 ************************************************************************/

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#define BUFFER_SIZE 1024

typedef struct _MyFILE {
    int _fd;
    char _buffer[BUFFER_SIZE];
    int _end;
} MyFILE;

MyFILE * _fopen(const char * pathname, const char * mode) 
{
    MyFILE *fp = NULL;
    assert(pathname);
    assert(mode);
    if (strcmp(mode, "r") == 0) {
        //TODO    
    } else if (strcmp(mode, "r") == 0) {
        //TODO    
    } else if (strcmp(mode, "r+") == 0) {
        //TODO    
    } else if (strcmp(mode, "w") == 0) {
        int fd = open(pathname, O_WRONLY | O_TRUNC | O_CREAT, 0666);
        if (fd >= 0) {
            fp = (MyFILE*)malloc(sizeof(MyFILE));
            memset(fp, 0, sizeof(MyFILE));
            fp->_fd = fd;
        }
    } else if (strcmp(mode, "w+") == 0) {
        //TODO    
    } else if (strcmp(mode, "a") == 0) {
        //TODO    
    } else if (strcmp(mode, "a+") == 0) {
        //TODO    
    }
    return fp;
}

void _fflush(MyFILE *fp)
{
    assert(fp);
    if (fp->_end != 0) {
        write(fp->_fd, fp->_buffer, fp->_end);
        syncfs(fp->_fd);
        fp->_end = 0;
    }
}

void _fputs(const char *message, MyFILE *fp)
{
    assert(message);
    assert(fp);
    strcpy(fp->_buffer + fp->_end, message);
    fp->_end += strlen(message);
    if (fp->_fd == 0) {
        //TODO 
    } else if (fp->_fd == 1) {
        if (fp->_buffer[fp->_end - 1] == '\n') {
            _fflush(fp);
        }
    } else if (fp->_fd == 2) {
        //TODO
    } else {
        //TODO 
    }
}

void _fclose(MyFILE * fp)
{
    assert(fp);
    _fflush(fp);
    close(fp->_fd);
    free(fp);
}

int main(int argc, char *argv[])
{
    close(1);
    MyFILE *fp = _fopen("log.txt", "w");
    if (!fp) {
        printf("open file error\n");
        return 1; 
    }
    _fputs("one:hello world", fp); 
    _fputs(" two:hello world\n", fp); 
    _fputs(" three:hello world", fp); 
    fork();
    _fclose(fp);
    return 0;
}
